/* ===================

AX2E (AXESCON XACML 2.0 Engine) is the Java authorization engine, which implements OASIS XACML 2.0 standard.
Copyright (C) 2007 AXESCON LLC

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA


Contact: AXESCON LLC - info{at}axescon.com

 =================== */
package axescon.xacml.api;

import axescon.xacml.model.ctx.XacmlCtx;
import axescon.xacml.model.policy.Expression;

/**
 * @author argyn
 * Date: Sep 28, 2005
 *         Responsibilities: represents any function , which could be used as
 *         functionId attribute.
 * This is AXESCON XACML Engine's extensibility point. New functions should implement this interface.
 * @see AbstractFn class.
 * @see MatchFn for those functions, which are used in
 *         MatchId attribute for target matching.
 */
public interface Fn {

    static final String FN_URN1 = "urn:oasis:names:tc:xacml:1.0:function:";
    static final String FN_URN2 = "urn:oasis:names:tc:xacml:2.0:function:";

    static final String STRING_EQUAL = FN_URN1 + "string-equal";
    static final String ANYURI_EQUAL = FN_URN1 + "anyURI-equal";
    static final String INTEGER_EQUAL = FN_URN1 + "integer-equal";
    static final String DOUBLE_EQUAL = FN_URN1 + "double-equal";
    static final String TIME_EQUAL = FN_URN1 + "time-equal";
    static final String DATETIME_EQUAL = FN_URN1 + "dateTime-equal";
    static final String DATE_EQUAL = FN_URN1 + "date-equal";
    static final String X500NAME_EQUAL = FN_URN1 + "x500Name-equal";
    static final String BOOLEAN_EQUAL = FN_URN1 + "boolean-equal";
    static final String RFC822NAME_EQUAL = FN_URN1 + "rfc822Name-equal";
    static final String HEXBINARY_EQUAL = FN_URN1 + "hexBinary-equal";
    static final String BASE64BINARY_EQUAL = FN_URN1 + "base64Binary-equal";
    static final String DAYTIMEDURATION_EQUAL = FN_URN1 + "dayTimeDuration-equal";
    static final String YEARMONTHDURATION_EQUAL = FN_URN1 + "yearMonthDuration-equal";

    static final String STRING_BAG = FN_URN1 + "string-bag";
    static final String ANYURI_BAG = FN_URN1 + "anyURI-bag";
    static final String INTEGER_BAG = FN_URN1 + "integer-bag";
    static final String DOUBLE_BAG = FN_URN1 + "double-bag";
    static final String TIME_BAG = FN_URN1 + "time-bag";
    static final String DATETIME_BAG = FN_URN1 + "dateTime-bag";
    static final String DATE_BAG = FN_URN1 + "date-bag";
    static final String X500NAME_BAG = FN_URN1 + "x500Name-bag";
    static final String BOOLEAN_BAG = FN_URN1 + "boolean-bag";
    static final String RFC822NAME_BAG = FN_URN1 + "rfc822Name-bag";
    static final String HEXBINARY_BAG = FN_URN1 + "hexBinary-bag";
    static final String BASE64BINARY_BAG = FN_URN1 + "base64Binary-bag";
    static final String DAYTIMEDURATION_BAG = FN_URN1 + "dayTimeDuration-bag";
    static final String YEARMONTHDURATION_BAG = FN_URN1 + "yearMonthDuration-bag";

    static final String STRING_GREATER_THAN_OR_EQUAL = FN_URN1 + "string-greater-than-or-equal";
    static final String ANYURI_GREATER_THAN_OR_EQUAL = FN_URN1 + "anyURI-greater-than-or-equal";
    static final String INTEGER_GREATER_THAN_OR_EQUAL = FN_URN1 + "integer-greater-than-or-equal";
    static final String DOUBLE_GREATER_THAN_OR_EQUAL = FN_URN1 + "double-greater-than-or-equal";
    static final String TIME_GREATER_THAN_OR_EQUAL = FN_URN1 + "time-greater-than-or-equal";
    static final String DATETIME_GREATER_THAN_OR_EQUAL = FN_URN1 + "dateTime-greater-than-or-equal";
    static final String DATE_GREATER_THAN_OR_EQUAL = FN_URN1 + "date-greater-than-or-equal";
    static final String X500NAME_GREATER_THAN_OR_EQUAL = FN_URN1 + "x500Name-greater-than-or-equal";

    static final String STRING_GREATER_THAN = FN_URN1 + "string-greater-than";
    static final String ANYURI_GREATER_THAN = FN_URN1 + "anyURI-greater-than";
    static final String INTEGER_GREATER_THAN = FN_URN1 + "integer-greater-than";
    static final String DOUBLE_GREATER_THAN = FN_URN1 + "double-greater-than";
    static final String TIME_GREATER_THAN = FN_URN1 + "time-greater-than";
    static final String DATETIME_GREATER_THAN = FN_URN1 + "dateTime-greater-than";
    static final String DATE_GREATER_THAN = FN_URN1 + "date-greater-than";
    static final String X500NAME_GREATER_THAN = FN_URN1 + "x500Name-greater-than";

    static final String STRING_LESS_THAN = FN_URN1 + "string-less-than";
    static final String ANYURI_LESS_THAN = FN_URN1 + "anyURI-less-than";
    static final String INTEGER_LESS_THAN = FN_URN1 + "integer-less-than";
    static final String DOUBLE_LESS_THAN = FN_URN1 + "double-less-than";
    static final String TIME_LESS_THAN = FN_URN1 + "time-less-than";
    static final String DATETIME_LESS_THAN = FN_URN1 + "dateTime-less-than";
    static final String DATE_LESS_THAN = FN_URN1 + "date-less-than";
    static final String X500NAME_LESS_THAN = FN_URN1 + "x500Name-less-than";

    static final String STRING_LESS_THAN_OR_EQUAL = FN_URN1 + "string-less-than-or-equal";
    static final String ANYURI_LESS_THAN_OR_EQUAL = FN_URN1 + "anyURI-less-than-or-equal";
    static final String INTEGER_LESS_THAN_OR_EQUAL = FN_URN1 + "integer-less-than-or-equal";
    static final String DOUBLE_LESS_THAN_OR_EQUAL = FN_URN1 + "double-less-than-or-equal";
    static final String TIME_LESS_THAN_OR_EQUAL = FN_URN1 + "time-less-than-or-equal";
    static final String DATETIME_LESS_THAN_OR_EQUAL = FN_URN1 + "dateTime-less-than-or-equal";
    static final String DATE_LESS_THAN_OR_EQUAL = FN_URN1 + "date-less-than-or-equal";
    static final String X500NAME_LESS_THAN_OR_EQUAL = FN_URN1 + "x500Name-less-than-or-equal";

    static final String INTEGER_SUBTRACT = FN_URN1 + "integer-subtract";
    static final String DOUBLE_SUBTRACT = FN_URN1 + "double-subtract";
    static final String INTEGER_ADD = FN_URN1 + "integer-add";
    static final String DOUBLE_ADD = FN_URN1 + "double-add";
    static final String INTEGER_MULTIPLY = FN_URN1 + "integer-multiply";
    static final String DOUBLE_MULTIPLY = FN_URN1 + "double-multiply";
    static final String INTEGER_DIVIDE = FN_URN1 + "integer-divide";
    static final String DOUBLE_DIVIDE = FN_URN1 + "double-divide";
    static final String INTEGER_MOD = FN_URN1 + "integer-mod";
    static final String DOUBLE_MOD = FN_URN1 + "double-mod";
    static final String ROUND = FN_URN1 + "round";
    static final String FLOOR = FN_URN1 + "floor";
    static final String INTEGER_ABS = FN_URN1 + "integer-abs";
    static final String DOUBLE_ABS = FN_URN1 + "double-abs";
    static final String DOUBLE_TO_INTEGER = FN_URN1 + "double-to-integer";
    static final String INTEGER_TO_DOUBLE = FN_URN1 + "integer-to-double";

    static final String DATETIME_ADD_DAYTIMEDURATION = FN_URN1 + "dateTime-add-dayTimeDuration";
    static final String DATETIME_SUBTRACT_DAYTIMEDURATION = FN_URN1 + "dateTime-subtract-dayTimeDuration";
    static final String DATETIME_ADD_YEARMONTHDURATION = FN_URN1 + "dateTime-add-yearMonthDuration";
    static final String DATETIME_SUBTRACT_YEARMONTHDURATION = FN_URN1 + "dateTime-subtract-yearMonthDuration";
    static final String DATE_ADD_YEARMONTHDURATION = FN_URN1 + "date-add-yearMonthDuration";
    static final String DATE_SUBTRACT_YEARMONTHDURATION = FN_URN1 + "date-subtract-yearMonthDuration";

    static final String STRING_REGEXP_MATCH = FN_URN1 + "string-regexp-match";
    static final String ANYURI_REGEXP_MATCH = FN_URN2 + "anyURI-regexp-match";
    static final String IPADDRESS_REGEXP_MATCH = FN_URN2 + "ipAddress-regexp-match";
    static final String DNSNAME_REGEXP_MATCH = FN_URN2 + "dnsName-regexp-match";
    static final String RFC822NAME_REGEXP_MATCH = FN_URN2 + "rfc822Name-regexp-match";
    static final String X500NAME_REGEXP_MATCH = FN_URN1 + "x500Name-regexp-match";

    static final String X500NAME_MATCH = FN_URN1 + "x500Name-match";
    static final String RFC822NAME_MATCH = FN_URN1 + "rfc822Name-match";

    static final String STRING_IS_IN = FN_URN1 + "string-is-in";
    static final String ANYURI_IS_IN = FN_URN1 + "anyURI-is-in";
    static final String IPADDRESS_IS_IN = FN_URN1 + "ipAddress-is-in";
    static final String DNSNAME_IS_IN = FN_URN1 + "dnsName-is-in";
    static final String RFC822NAME_IS_IN = FN_URN1 + "rfc822Name-is-in";
    static final String X500NAME_IS_IN = FN_URN1 + "x500Name-is-in";
    static final String INTEGER_IS_IN = FN_URN1 + "integer-is-in";
    static final String DOUBLE_IS_IN = FN_URN1 + "double-is-in";
    static final String TIME_IS_IN = FN_URN1 + "time-is-in";
    static final String DATETIME_IS_IN = FN_URN1 + "dateTime-is-in";
    static final String DATE_IS_IN = FN_URN1 + "date-is-in";
    static final String HEXBINARY_IS_IN = FN_URN1 + "hexBinary-is-in";
    static final String BASE64BINARY_IS_IN = FN_URN1 + "base64Binary-is-in";
    static final String BOOLEAN_IS_IN = FN_URN1 + "boolean-is-in";
    static final String DAYTIMEDURATION_IS_IN = FN_URN1 + "dayTimeDuration-is-in";
    static final String YEARMONTHDURATION_IS_IN = FN_URN1 + "yearMonthDuration-is-in";

    static final String STRING_ONE_AND_ONLY = FN_URN1 + "string-one-and-only";
    static final String ANYURI_ONE_AND_ONLY = FN_URN1 + "anyURI-one-and-only";
    static final String IPADDRESS_ONE_AND_ONLY = FN_URN1 + "ipAddress-one-and-only";
    static final String DNSNAME_ONE_AND_ONLY = FN_URN1 + "dnsName-one-and-only";
    static final String RFC822NAME_ONE_AND_ONLY = FN_URN1 + "rfc822Name-one-and-only";
    static final String X500NAME_ONE_AND_ONLY = FN_URN1 + "x500Name-one-and-only";
    static final String INTEGER_ONE_AND_ONLY = FN_URN1 + "integer-one-and-only";
    static final String DOUBLE_ONE_AND_ONLY = FN_URN1 + "double-one-and-only";
    static final String TIME_ONE_AND_ONLY = FN_URN1 + "time-one-and-only";
    static final String DATETIME_ONE_AND_ONLY = FN_URN1 + "dateTime-one-and-only";
    static final String DATE_ONE_AND_ONLY = FN_URN1 + "date-one-and-only";
    static final String HEXBINARY_ONE_AND_ONLY = FN_URN1 + "hexBinary-one-and-only";
    static final String BASE64BINARY_ONE_AND_ONLY = FN_URN1 + "base64Binary-one-and-only";
    static final String BOOLEAN_ONE_AND_ONLY = FN_URN1 + "boolean-one-and-only";
    static final String DAYTIMEDURATION_ONE_AND_ONLY = FN_URN1 + "dayTimeDuration-one-and-only";
    static final String YEARMONTHDURATION_ONE_AND_ONLY = FN_URN1 + "yearMonthDuration-one-and-only";

    static final String STRING_BAG_SIZE = FN_URN1 + "string-bag-size";
    static final String ANYURI_BAG_SIZE = FN_URN1 + "anyURI-bag-size";
    static final String IPADDRESS_BAG_SIZE = FN_URN1 + "ipAddress-bag-size";
    static final String DNSNAME_BAG_SIZE = FN_URN1 + "dnsName-bag-size";
    static final String RFC822NAME_BAG_SIZE = FN_URN1 + "rfc822Name-bag-size";
    static final String X500NAME_BAG_SIZE = FN_URN1 + "x500Name-bag-size";
    static final String INTEGER_BAG_SIZE = FN_URN1 + "integer-bag-size";
    static final String DOUBLE_BAG_SIZE = FN_URN1 + "double-bag-size";
    static final String TIME_BAG_SIZE = FN_URN1 + "time-bag-size";
    static final String DATETIME_BAG_SIZE = FN_URN1 + "dateTime-bag-size";
    static final String DATE_BAG_SIZE = FN_URN1 + "date-bag-size";
    static final String BOOLEAN_BAG_SIZE = FN_URN1 + "boolean-bag-size";
    static final String BASE64BINARY_BAG_SIZE = FN_URN1 + "base64Binary-bag-size";
    static final String HEXBINARY_BAG_SIZE = FN_URN1 + "hexBinary-bag-size";
    static final String DAYTIMEDURATION_BAG_SIZE = FN_URN1 + "dayTimeDuration-bag-size";
    static final String YEARMONTHDURATION_BAG_SIZE = FN_URN1 + "yearMonthDuration-bag-size";

    static final String STRING_INTERSECTION = FN_URN1 + "string-intersection";
    static final String ANYURI_INTERSECTION = FN_URN1 + "anyURI-intersection";
    static final String INTEGER_INTERSECTION = FN_URN1 + "integer-intersection";
    static final String DOUBLE_INTERSECTION = FN_URN1 + "double-intersection";
    static final String TIME_INTERSECTION = FN_URN1 + "time-intersection";
    static final String DATETIME_INTERSECTION = FN_URN1 + "dateTime-intersection";
    static final String DATE_INTERSECTION = FN_URN1 + "date-intersection";
    static final String X500NAME_INTERSECTION = FN_URN1 + "x500Name-intersection";
    static final String BOOLEAN_INTERSECTION = FN_URN1 + "boolean-intersection";
    static final String RFC822NAME_INTERSECTION = FN_URN1 + "rfc822Name-intersection";
    static final String HEXBINARY_INTERSECTION = FN_URN1 + "hexBinary-intersection";
    static final String BASE64BINARY_INTERSECTION = FN_URN1 + "base64Binary-intersection";
    static final String DAYTIMEDURATION_INTERSECTION = FN_URN1 + "dayTimeDuration-intersection";
    static final String YEARMONTHDURATION_INTERSECTION = FN_URN1 + "yearMonthDuration-intersection";

    static final String STRING_UNION = FN_URN1 + "string-union";
    static final String ANYURI_UNION = FN_URN1 + "anyURI-union";
    static final String INTEGER_UNION = FN_URN1 + "integer-union";
    static final String DOUBLE_UNION = FN_URN1 + "double-union";
    static final String TIME_UNION = FN_URN1 + "time-union";
    static final String DATETIME_UNION = FN_URN1 + "dateTime-union";
    static final String DATE_UNION = FN_URN1 + "date-union";
    static final String X500NAME_UNION = FN_URN1 + "x500Name-union";
    static final String BOOLEAN_UNION = FN_URN1 + "boolean-union";
    static final String RFC822NAME_UNION = FN_URN1 + "rfc822Name-union";
    static final String HEXBINARY_UNION = FN_URN1 + "hexBinary-union";
    static final String BASE64BINARY_UNION = FN_URN1 + "base64Binary-union";
    static final String DAYTIMEDURATION_UNION = FN_URN1 + "dayTimeDuration-union";
    static final String YEARMONTHDURATION_UNION = FN_URN1 + "yearMonthDuration-union";

    static final String STRING_SUBSET = FN_URN1 + "string-subset";
    static final String ANYURI_SUBSET = FN_URN1 + "anyURI-subset";
    static final String INTEGER_SUBSET = FN_URN1 + "integer-subset";
    static final String DOUBLE_SUBSET = FN_URN1 + "double-subset";
    static final String TIME_SUBSET = FN_URN1 + "time-subset";
    static final String DATETIME_SUBSET = FN_URN1 + "dateTime-subset";
    static final String DATE_SUBSET = FN_URN1 + "date-subset";
    static final String X500NAME_SUBSET = FN_URN1 + "x500Name-subset";
    static final String BOOLEAN_SUBSET = FN_URN1 + "boolean-subset";
    static final String RFC822NAME_SUBSET = FN_URN1 + "rfc822Name-subset";
    static final String HEXBINARY_SUBSET = FN_URN1 + "hexBinary-subset";
    static final String BASE64BINARY_SUBSET = FN_URN1 + "base64Binary-subset";
    static final String DAYTIMEDURATION_SUBSET = FN_URN1 + "dayTimeDuration-subset";
    static final String YEARMONTHDURATION_SUBSET = FN_URN1 + "yearMonthDuration-subset";

    static final String STRING_SET_EQUALS = FN_URN1 + "string-set-equals";
    static final String ANYURI_SET_EQUALS = FN_URN1 + "anyURI-set-equals";
    static final String INTEGER_SET_EQUALS = FN_URN1 + "integer-set-equals";
    static final String DOUBLE_SET_EQUALS = FN_URN1 + "double-set-equals";
    static final String TIME_SET_EQUALS = FN_URN1 + "time-set-equals";
    static final String DATETIME_SET_EQUALS = FN_URN1 + "dateTime-set-equals";
    static final String DATE_SET_EQUALS = FN_URN1 + "date-set-equals";
    static final String X500NAME_SET_EQUALS = FN_URN1 + "x500Name-set-equals";
    static final String BOOLEAN_SET_EQUALS = FN_URN1 + "boolean-set-equals";
    static final String RFC822NAME_SET_EQUALS = FN_URN1 + "rfc822Name-set-equals";
    static final String HEXBINARY_SET_EQUALS = FN_URN1 + "hexBinary-set-equals";
    static final String BASE64BINARY_SET_EQUALS = FN_URN1 + "base64Binary-set-equals";
    static final String DAYTIMEDURATION_SET_EQUALS = FN_URN1 + "dayTimeDuration-set-equals";
    static final String YEARMONTHDURATION_SET_EQUALS = FN_URN1 + "yearMonthDuration-set-equals";

    static final String STRING_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "string-at-least-one-member-of";
    static final String ANYURI_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "anyURI-at-least-one-member-of";
    static final String INTEGER_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "integer-at-least-one-member-of";
    static final String DOUBLE_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "double-at-least-one-member-of";
    static final String TIME_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "time-at-least-one-member-of";
    static final String DATETIME_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "dateTime-at-least-one-member-of";
    static final String DATE_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "date-at-least-one-member-of";
    static final String X500NAME_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "x500Name-at-least-one-member-of";
    static final String BOOLEAN_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "boolean-at-least-one-member-of";
    static final String RFC822NAME_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "rfc822Name-at-least-one-member-of";
    static final String HEXBINARY_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "hexBinary-at-least-one-member-of";
    static final String BASE64BINARY_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "base64Binary-at-least-one-member-of";
    static final String DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "dayTimeDuration-at-least-one-member-of";
    static final String YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF = FN_URN1 + "yearMonthDuration-at-least-one-member-of";


    static final String OR = FN_URN1 + "or";
    static final String AND = FN_URN1 + "and";
    static final String NOT = FN_URN1 + "not";
    static final String N_OF = FN_URN1 + "n-of";

    static final String ANY_OF = FN_URN1 + "any-of";
    static final String ALL_OF = FN_URN1 + "all-of";
    static final String ANY_OF_ANY = FN_URN1 + "any-of-any";
    static final String ALL_OF_ANY = FN_URN1 + "all-of-any";
    static final String ALL_OF_ALL = FN_URN1 + "all-of-all";
    static final String ANY_OF_ALL = FN_URN1 + "any-of-all";
    static final String MAP = FN_URN1 + "map";

    static final String STRING_NORMALIZE_SPACE = FN_URN1 + "string-normalize-space";
    static final String STRING_NORMALIZE_TO_LOWER_CASE = FN_URN1 + "string-normalize-to-lower-case";

    static final String STRING_CONCATENATE = FN_URN2 + "string-concatenate";
    static final String URL_STRING_CONCATENATE = FN_URN2 + "url-string-concatenate";


    static final String XPATH_NODE_COUNT = FN_URN1 + "xpath-node-count";
    static final String XPATH_NODE_EQUAL = FN_URN1 + "xpath-node-equal";
    static final String XPATH_NODE_MATCH = FN_URN1 + "xpath-node-match";

    static final String TIME_IN_RANGE = FN_URN2 + "time-in-range";

    /**
     * executes this function, accepting function arguments, which are to be evaluated to Liquid objects.
     * this function checks types of arguments.
     * @param args function arguments
     * @param ch context handler
     * @param req request
     * @param ee expression evaluator
     * @return evaluation result
     * @throws XacmlException
     * @throws ExpressionEvalIndeterminateException
     *
     */
    Liquid exec(Expression[] args, CtxHandler ch, XacmlCtx req, ExpressionEvaluator ee) throws XacmlException
            , ExpressionEvalIndeterminateException;

    /**
     * executes this function, accepting function arguments, which were already evaluated to Liquid objects.
     * this assumes that arguments were already type checked.
     * @param args
     * @return function execution result
     * @throws XacmlException
     * @throws ExpressionEvalIndeterminateException
     *
     */
    Liquid exec(Liquid[] args) throws XacmlException
            , ExpressionEvalIndeterminateException;

    /**
     * set function factory, which is used if this function needs
     *                  to use other functions
     * @param fnFactory factory
     */
    void setFnFactory(FnFactory fnFactory);

    /**
     * returns urn of function
     * @return function urn.
     */
    String getFnUrn();

    /**
     * sets function urn
     * @param urn
     */
    void setFnUrn(String urn);

    /**
     * returns function arg data types
     * @return array of Java types of function arguments
     */
    Class[] getDataTypes();

    /**
     * sets function argument datatypes
     * @param dataTypes
     * @throws XacmlException
     */
    void setDataTypes(Class[] dataTypes) throws XacmlException;

    /**
     * returns function return data types
     * @return Java type of function return value
     * @throws ExpressionEvalIndeterminateException
     */
    public Class getReturnDataType() throws ExpressionEvalIndeterminateException;

    /**
     * this is the length of argument data type list. this method is used
     * by abstract function implementation to check that the correct number of
     * data types are being set.
     * <p/>
     * this supports variable arg list like fn(arg0, arg1, arg2, ...), where
     * getArgTypeListLength returns 3, and arguments represented by '...'
     * should be of the same type as last data type i.e. arg2.
     *
     * @return number of argument data types
     */
    int getArgTypeListLength();


    /**
     * min number of arguments required by function. this method is used
     * by abstract function implementation to check that the correct number of
     * args are being passed to a function.
     * <p/>
     * this supports variable arg list like fn(arg0, arg1, arg2, ...).
     * when getMinArgListLength() returns 2, then fn needs only first
     * two args to execute.
     *
     * @return min number of arguments required by function. by default it's the
     *         same as getArgTypeListLength().
     */
    int getMinArgListLength();

    /**
     * max number of arguments required by function. this method is used
     * by abstract function implementation to check that the correct number of
     * args are being passed to a function.
     * <p/>
     * this supports variable arg list like fn(arg0, arg1, arg2, ...).
     * when getMinArgListLength() returns 5, then fn can take only first
     * five args to execute, i.e. arg0, arg1,...,arg4.
     *
     * @return max number of arguments required by function. negative if unlimited.
     *         by default it's the same as getMinArgListLength().
     */
    int getMaxArgListLength();


    /**
     * array containing urns of all mandatory standard functions
     */
    public static final String[] mandatoryFns = new String[]

            {
                    STRING_EQUAL,
                    ANYURI_EQUAL,
                    INTEGER_EQUAL,
                    DOUBLE_EQUAL,
                    TIME_EQUAL,
                    DATETIME_EQUAL,
                    DATE_EQUAL,
                    X500NAME_EQUAL,
                    BOOLEAN_EQUAL,
                    RFC822NAME_EQUAL,
                    HEXBINARY_EQUAL,
                    BASE64BINARY_EQUAL,
                    DAYTIMEDURATION_EQUAL,
                    YEARMONTHDURATION_EQUAL,

                    STRING_BAG,
                    ANYURI_BAG,
                    INTEGER_BAG,
                    DOUBLE_BAG,
                    TIME_BAG,
                    DATETIME_BAG,
                    DATE_BAG,
                    X500NAME_BAG,
                    BOOLEAN_BAG,
                    RFC822NAME_BAG,
                    HEXBINARY_BAG,
                    BASE64BINARY_BAG,
                    DAYTIMEDURATION_BAG,
                    YEARMONTHDURATION_BAG,

                    STRING_GREATER_THAN_OR_EQUAL,
                    ANYURI_GREATER_THAN_OR_EQUAL,
                    INTEGER_GREATER_THAN_OR_EQUAL,
                    DOUBLE_GREATER_THAN_OR_EQUAL,
                    TIME_GREATER_THAN_OR_EQUAL,
                    DATETIME_GREATER_THAN_OR_EQUAL,
                    DATE_GREATER_THAN_OR_EQUAL,
                    X500NAME_GREATER_THAN_OR_EQUAL,

                    STRING_GREATER_THAN,
                    ANYURI_GREATER_THAN,
                    INTEGER_GREATER_THAN,
                    DOUBLE_GREATER_THAN,
                    TIME_GREATER_THAN,
                    DATETIME_GREATER_THAN,
                    DATE_GREATER_THAN,
                    X500NAME_GREATER_THAN,

                    STRING_LESS_THAN,
                    ANYURI_LESS_THAN,
                    INTEGER_LESS_THAN,
                    DOUBLE_LESS_THAN,
                    TIME_LESS_THAN,
                    DATETIME_LESS_THAN,
                    DATE_LESS_THAN,
                    X500NAME_LESS_THAN,

                    STRING_LESS_THAN_OR_EQUAL,
                    ANYURI_LESS_THAN_OR_EQUAL,
                    INTEGER_LESS_THAN_OR_EQUAL,
                    DOUBLE_LESS_THAN_OR_EQUAL,
                    TIME_LESS_THAN_OR_EQUAL,
                    DATETIME_LESS_THAN_OR_EQUAL,
                    DATE_LESS_THAN_OR_EQUAL,
                    X500NAME_LESS_THAN_OR_EQUAL,

                    INTEGER_SUBTRACT,
                    DOUBLE_SUBTRACT,
                    INTEGER_ADD,
                    DOUBLE_ADD,
                    INTEGER_MULTIPLY,
                    DOUBLE_MULTIPLY,
                    INTEGER_DIVIDE,
                    DOUBLE_DIVIDE,
                    INTEGER_MOD,
                    DOUBLE_MOD,
                    ROUND,
                    FLOOR,
                    INTEGER_ABS,
                    DOUBLE_ABS,
                    DOUBLE_TO_INTEGER,
                    INTEGER_TO_DOUBLE,

                    DATETIME_ADD_DAYTIMEDURATION,
                    DATETIME_SUBTRACT_DAYTIMEDURATION,
                    DATETIME_ADD_YEARMONTHDURATION,
                    DATETIME_SUBTRACT_YEARMONTHDURATION,
                    DATE_ADD_YEARMONTHDURATION,
                    DATE_SUBTRACT_YEARMONTHDURATION,

                    STRING_REGEXP_MATCH,
                    ANYURI_REGEXP_MATCH,
                    IPADDRESS_REGEXP_MATCH,
                    DNSNAME_REGEXP_MATCH,
                    RFC822NAME_REGEXP_MATCH,
                    X500NAME_REGEXP_MATCH,

                    X500NAME_MATCH,
                    RFC822NAME_MATCH,

                    STRING_IS_IN,
                    ANYURI_IS_IN,
                    IPADDRESS_IS_IN,
                    DNSNAME_IS_IN,
                    RFC822NAME_IS_IN,
                    X500NAME_IS_IN,
                    INTEGER_IS_IN,
                    DOUBLE_IS_IN,
                    TIME_IS_IN,
                    DATETIME_IS_IN,
                    DATE_IS_IN,
                    HEXBINARY_IS_IN,
                    BASE64BINARY_IS_IN,
                    BOOLEAN_IS_IN,
                    DAYTIMEDURATION_IS_IN,
                    YEARMONTHDURATION_IS_IN,

                    STRING_ONE_AND_ONLY,
                    ANYURI_ONE_AND_ONLY,
                    IPADDRESS_ONE_AND_ONLY,
                    DNSNAME_ONE_AND_ONLY,
                    RFC822NAME_ONE_AND_ONLY,
                    X500NAME_ONE_AND_ONLY,
                    INTEGER_ONE_AND_ONLY,
                    DOUBLE_ONE_AND_ONLY,
                    TIME_ONE_AND_ONLY,
                    DATETIME_ONE_AND_ONLY,
                    DATE_ONE_AND_ONLY,
                    HEXBINARY_ONE_AND_ONLY,
                    BASE64BINARY_ONE_AND_ONLY,
                    BOOLEAN_ONE_AND_ONLY,
                    DAYTIMEDURATION_ONE_AND_ONLY,
                    YEARMONTHDURATION_ONE_AND_ONLY,

                    STRING_BAG_SIZE,
                    ANYURI_BAG_SIZE,
                    IPADDRESS_BAG_SIZE,
                    DNSNAME_BAG_SIZE,
                    RFC822NAME_BAG_SIZE,
                    X500NAME_BAG_SIZE,
                    INTEGER_BAG_SIZE,
                    DOUBLE_BAG_SIZE,
                    TIME_BAG_SIZE,
                    DATETIME_BAG_SIZE,
                    DATE_BAG_SIZE,
                    BOOLEAN_BAG_SIZE,
                    BASE64BINARY_BAG_SIZE,
                    HEXBINARY_BAG_SIZE,
                    DAYTIMEDURATION_BAG_SIZE,
                    YEARMONTHDURATION_BAG_SIZE,

                    STRING_INTERSECTION,
                    ANYURI_INTERSECTION,
                    INTEGER_INTERSECTION,
                    DOUBLE_INTERSECTION,
                    TIME_INTERSECTION,
                    DATETIME_INTERSECTION,
                    DATE_INTERSECTION,
                    X500NAME_INTERSECTION,
                    BOOLEAN_INTERSECTION,
                    RFC822NAME_INTERSECTION,
                    HEXBINARY_INTERSECTION,
                    BASE64BINARY_INTERSECTION,
                    DAYTIMEDURATION_INTERSECTION,
                    YEARMONTHDURATION_INTERSECTION,

                    STRING_UNION,
                    ANYURI_UNION,
                    INTEGER_UNION,
                    DOUBLE_UNION,
                    TIME_UNION,
                    DATETIME_UNION,
                    DATE_UNION,
                    X500NAME_UNION,
                    BOOLEAN_UNION,
                    RFC822NAME_UNION,
                    HEXBINARY_UNION,
                    BASE64BINARY_UNION,
                    DAYTIMEDURATION_UNION,
                    YEARMONTHDURATION_UNION,

                    STRING_SUBSET,
                    ANYURI_SUBSET,
                    INTEGER_SUBSET,
                    DOUBLE_SUBSET,
                    TIME_SUBSET,
                    DATETIME_SUBSET,
                    DATE_SUBSET,
                    X500NAME_SUBSET,
                    BOOLEAN_SUBSET,
                    RFC822NAME_SUBSET,
                    HEXBINARY_SUBSET,
                    BASE64BINARY_SUBSET,
                    DAYTIMEDURATION_SUBSET,
                    YEARMONTHDURATION_SUBSET,

                    STRING_SET_EQUALS,
                    ANYURI_SET_EQUALS,
                    INTEGER_SET_EQUALS,
                    DOUBLE_SET_EQUALS,
                    TIME_SET_EQUALS,
                    DATETIME_SET_EQUALS,
                    DATE_SET_EQUALS,
                    X500NAME_SET_EQUALS,
                    BOOLEAN_SET_EQUALS,
                    RFC822NAME_SET_EQUALS,
                    HEXBINARY_SET_EQUALS,
                    BASE64BINARY_SET_EQUALS,
                    DAYTIMEDURATION_SET_EQUALS,
                    YEARMONTHDURATION_SET_EQUALS,

                    STRING_AT_LEAST_ONE_MEMBER_OF,
                    ANYURI_AT_LEAST_ONE_MEMBER_OF,
                    INTEGER_AT_LEAST_ONE_MEMBER_OF,
                    DOUBLE_AT_LEAST_ONE_MEMBER_OF,
                    TIME_AT_LEAST_ONE_MEMBER_OF,
                    DATETIME_AT_LEAST_ONE_MEMBER_OF,
                    DATE_AT_LEAST_ONE_MEMBER_OF,
                    X500NAME_AT_LEAST_ONE_MEMBER_OF,
                    BOOLEAN_AT_LEAST_ONE_MEMBER_OF,
                    RFC822NAME_AT_LEAST_ONE_MEMBER_OF,
                    HEXBINARY_AT_LEAST_ONE_MEMBER_OF,
                    BASE64BINARY_AT_LEAST_ONE_MEMBER_OF,
                    DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF,
                    YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF,


                    OR,
                    AND,
                    NOT,
                    N_OF,

                    ANY_OF,
                    ALL_OF,
                    ANY_OF_ANY,
                    ALL_OF_ANY,
                    ALL_OF_ALL,
                    ANY_OF_ALL,
                    MAP,

                    STRING_NORMALIZE_SPACE,
                    STRING_NORMALIZE_TO_LOWER_CASE,

                    STRING_CONCATENATE,
                    URL_STRING_CONCATENATE
            };

    /**
     * array containing urns of all standard optional functions
     */
    public static final String[] optionalFns = new String[]

            {


                    XPATH_NODE_COUNT,
                    XPATH_NODE_EQUAL,
                    XPATH_NODE_MATCH
            };


    /**
     * get the function factory
     * @return function factory reference
     */
    FnFactory getFnFactory();
}
